/*
 * Copyright 1998-2011 by SLIB,
 * 70 rue Villette, 69003 Lyon, France
 * All rights reserved.
 *
 * This software is the confidential and proprietary information
 * of SLIB. (&quot;Confidential Information&quot;).  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with SLIB.
 */
package com.petot.claude.gwt.example.client.place;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.place.shared.PlaceChangeEvent;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.user.client.ui.HasConstrainedValue;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.HandlerRegistration;

/**
 * <code>NavigationPlacePicker</code>
 * Drives a {@link ValueChangeHandler} populated with {@link NavigationPlace} instances,
 * keeping it in sync with the {@link PlaceController}'s notion of the current place,
 * and firing place change events as selections are made.
 *
 * @version $Revision: 6 $ $Date: 2012-02-22 10:46:26 +0000 (Wed, 22 Feb 2012) $
 * @author petotcl, $Author: claude.petot@gmail.com $
 */
public class NavigationPlacePicker implements ValueChangeHandler<NavigationPlace>, PlaceChangeEvent.Handler {

    private final List<HasConstrainedValue<NavigationPlace>> viewsList;
    private final PlaceController placeController;
    private final PlaceToNavigationPlace placeToNavigationPlace;

    public NavigationPlacePicker( final PlaceController placeController, final PlaceToNavigationPlace pplaceToNavigationPlace ) {
        this.placeController = placeController;
        this.placeToNavigationPlace = pplaceToNavigationPlace;
        this.viewsList = new ArrayList<HasConstrainedValue<NavigationPlace>>();
    }

    @Override
    public void onPlaceChange( final PlaceChangeEvent event ) {
        for ( HasConstrainedValue<NavigationPlace> lView : this.viewsList ) {
            lView.setValue( this.placeToNavigationPlace.navigationPlaceFor( event.getNewPlace() ), false );
        }
    }

    @Override
    public void onValueChange( final ValueChangeEvent<NavigationPlace> event ) {
        this.placeController.goTo( event.getValue() );
    }

    public HandlerRegistration register( final EventBus pEventBus, final HasConstrainedValue<NavigationPlace> pView ) {

        // Ajout de la vue
        this.viewsList.add( pView );

        final HandlerRegistration placeRegistration = pEventBus.addHandler( PlaceChangeEvent.TYPE, this );

        final HandlerRegistration viewRegistration = pView.addValueChangeHandler( this );

        return new HandlerRegistration() {

            @Override
            public void removeHandler() {
                placeRegistration.removeHandler();
                viewRegistration.removeHandler();
                NavigationPlacePicker.this.viewsList.remove( pView );
            }
        };
    }
}
